package com.atguigu.gmall.service;

import com.alibaba.fastjson.JSONObject;
import com.atguigu.gmall.common.entity.GmallCorrelationData;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.UUID;

/**
 * @Author: 李旭
 * @Time: 15:15
 * @Description:
 *   提供 普通消息   延迟消息
 *
 */
@Component
@SuppressWarnings("all")
public class RabbitService {

    @Autowired
    private RabbitTemplate rabbitTemplate;//生产者  客户端
    @Autowired
    private RedisTemplate redisTemplate;

    //发普通消息
    public boolean sendMessage(String exchange,String routingKey,Object msg){
        //回调的对象  目标：为了发消息失败应答之后 重新发送所需要的对象
        GmallCorrelationData correlationData = new GmallCorrelationData();
        //唯一  ID
        String uuid = UUID.randomUUID().toString();
        correlationData.setId(uuid);
        System.out.println("uuid:" + uuid);
        //交换机
        correlationData.setExchange(exchange);
        //RoutingKey
        correlationData.setRoutingKey(routingKey);
        //消息
        correlationData.setMessage(msg);
        //外力 Redis
        String cacheKey = "mq:retry:message";
        redisTemplate.opsForHash().put(cacheKey,uuid, JSONObject.toJSONString(correlationData));//队列应答失败
        //发消息
        rabbitTemplate.convertAndSend(exchange,routingKey,msg,correlationData);//交换机应答失败
        return true;
    }
    //发送死信延迟消息
    public void sendDeadLetterMessage(String exchange,String routingKey,Object msg,int time){

        //回调的对象  目标：为了发消息失败应答之后 重新发送所需要的对象
        GmallCorrelationData correlationData = new GmallCorrelationData();
        //唯一  ID
        String uuid = UUID.randomUUID().toString();
        correlationData.setId(uuid);
        System.out.println("uuid:" + uuid);
        //交换机
        correlationData.setExchange(exchange);
        //RoutingKey
        correlationData.setRoutingKey(routingKey);
        //消息
        correlationData.setMessage(msg);

        //是延迟消息吗
        correlationData.setDelay(true);
        //延迟时间
        correlationData.setDelayTime(time);
        //外力 Redis
        String cacheKey = "mq:retry:message";
        redisTemplate.opsForHash().put(cacheKey,uuid, JSONObject.toJSONString(correlationData));//队列应答失败
        //发延迟消息 基于死信 过期 TTL
        rabbitTemplate.convertAndSend(exchange,routingKey,msg,message -> {
            //过期时间  毫秒
            System.out.println("发消息的时间：" + new Date());
            message.getMessageProperties().setExpiration(String.valueOf(time*1000));
            return message;
        },correlationData);

    }
    //基于插件的延迟消息
    public void sendDelayMessage(String exchange,String routingKey,Object msg,int time){
        //回调的对象  目标：为了发消息失败应答之后 重新发送所需要的对象
        GmallCorrelationData correlationData = new GmallCorrelationData();
        //唯一  ID
        String uuid = UUID.randomUUID().toString();
        correlationData.setId(uuid);
        System.out.println("uuid:" + uuid);
        //交换机
        correlationData.setExchange(exchange);
        //RoutingKey
        correlationData.setRoutingKey(routingKey);
        //消息
        correlationData.setMessage(msg);

        //是延迟消息吗
        correlationData.setDelay(true);
        //延迟时间
        correlationData.setDelayTime(time);
        //是插件
        correlationData.setChaJian(true);
        //外力 Redis
        String cacheKey = "mq:retry:message";
        redisTemplate.opsForHash().put(cacheKey,uuid, JSONObject.toJSONString(correlationData));//队列应答失败
        //发延迟消息 基于插件
        rabbitTemplate.convertAndSend(exchange,routingKey,msg,message -> {
            //过期时间  毫秒
            System.out.println("基于插件发消息的时间：" + new Date());
            message.getMessageProperties().setDelay(time*1000);
            return message;
        },correlationData);

    }
}
